package io.renren.common.utils;

import cn.hutool.core.util.StrUtil;
import io.renren.common.exception.RRException;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class BigDecimalUtils {
    public static final int DEFAULT_SCALE = 2;
    public static final int DEFAULT_THREE_SCALE = 3;
    public static final BigDecimal BIG_1000 = BigDecimal.valueOf(1000L);
    public static final BigDecimal BIG_100 = BigDecimal.valueOf(100L);

    public BigDecimalUtils() {
    }

    public static BigDecimal format(BigDecimal value) {
        if (value == null) {
            value = new BigDecimal(0);
        }

        return value.setScale(2, 4);
    }

    public static BigDecimal format(BigDecimal value, int scale) {
        if (value == null) {
            value = new BigDecimal(0);
        }

        return value.setScale(scale, 4);
    }

    public static long multiply(BigDecimal value, int m) {
        return value == null ? 0L : value.multiply(new BigDecimal(m)).longValue();
    }

    public static BigDecimal multiply(BigDecimal a, BigDecimal b) {
        return a == null ? BigDecimal.ZERO : a.multiply(b);
    }

    public static BigDecimal _multiply(BigDecimal value, int m) {
        return value == null ? new BigDecimal(0) : value.multiply(new BigDecimal(m));
    }

    public static BigDecimal divide(BigDecimal value, int m) {
        return value == null ? new BigDecimal(0) : value.divide(new BigDecimal(m));
    }

    public static int divide(BigDecimal value, BigDecimal m) {
        return value == null ? BigDecimal.ZERO.intValue() : value.divide(m).setScale(0, RoundingMode.DOWN).intValue();
    }

    public static BigDecimal divide(BigDecimal value, BigDecimal m, int scale) {
        return value != null && m != null ? value.divide(m, scale, 6) : BigDecimal.ZERO;
    }

    public static BigDecimal divideScale3(BigDecimal dividend, BigDecimal divisor) {
        return dividend != null && divisor != null && divisor.compareTo(BigDecimal.ZERO) != 0 ? dividend.divide(divisor, 3, 1) : BigDecimal.ZERO;
    }

    public static BigDecimal divideScale2(BigDecimal dividend, BigDecimal divisor) {
        return divide(dividend, divisor, 2);
    }

    public static BigDecimal scale2(BigDecimal price) {
        return price != null && BigDecimal.ZERO.compareTo(price) != 0 ? price.setScale(2, 5) : BigDecimal.ZERO;
    }

    public static BigDecimal divide(long value, int m) {
        return divide(new BigDecimal(value), m);
    }

    public static BigDecimal add(BigDecimal a, BigDecimal b) {
        if (a == null) {
            return b;
        } else {
            return b == null ? a : a.add(b);
        }
    }

    public static BigDecimal add(String a, String b) {
        return add(convert(a), convert(b));
    }

    public static BigDecimal subtract(BigDecimal a, BigDecimal b) {
        return a.subtract(b);
    }

    public static BigDecimal convert(String amount) {
        return convert(amount, BigDecimal.ZERO);
    }

    public static BigDecimal convert(String amount, BigDecimal defaultAmount) {
        if (StrUtil.isBlank(amount)) {
            return defaultAmount;
        } else {
            BigDecimal val = new BigDecimal(amount);
            return val;
        }
    }

    public static String convertStr(BigDecimal decimal) {
        return decimal == null ? BigDecimal.ZERO.toString() : decimal.stripTrailingZeros().toPlainString();
    }

    public static int compare(BigDecimal max, String min) {
        BigDecimal minx = convert(min);
        return compare(max, minx);
    }

    public static int compare(BigDecimal max, BigDecimal min) {
        if (max == null) {
            return -1;
        } else {
            return min == null ? 1 : max.compareTo(min);
        }
    }

    public static boolean compare(BigDecimal v, BigDecimal max, BigDecimal min) {
        return v.compareTo(min) == 1 && v.compareTo(max) <= 0;
    }

    public static int compare(BigDecimal source, int target) {
        BigDecimal targetDecimal = new BigDecimal(target);
        return source.compareTo(targetDecimal);
    }

    public static boolean compareBigThrowEx(BigDecimal max, BigDecimal min) {
        int flag = compare(max, min);
        if (flag == -1) {
            throw new RRException("参数错误");
        } else {
            return true;
        }
    }

    public static BigDecimal negate(BigDecimal money) {
        return money == null ? BigDecimal.ZERO : money.negate();
    }

    public static BigDecimal roundNumber(BigDecimal a) {
        return a == null ? BigDecimal.ZERO : a.setScale(0, RoundingMode.DOWN);
    }

    public static BigDecimal roundDecimal(BigDecimal a) {
        return a == null ? BigDecimal.ZERO : a.subtract(roundNumber(a));
    }

    public static BigDecimal mbs(BigDecimal money) {
        return money.abs();
    }

    public static BigDecimal penny2Dollar(Long penny) {
        return penny == null ? BigDecimal.ZERO : BigDecimal.valueOf(penny).divide(BIG_100);
    }

    public static BigDecimal penny2Dollar(Integer penny) {
        return penny == null ? BigDecimal.ZERO : BigDecimal.valueOf((long)penny).divide(BIG_100);
    }

    public static Integer dollar2Penny(BigDecimal amount) {
        return amount == null ? 0 : amount.multiply(BIG_100).intValue();
    }

    public static BigDecimal thousandThan(Integer amount) {
        return amount == null ? BigDecimal.ZERO : BigDecimal.valueOf((long)amount).divide(BIG_1000);
    }

    public static BigDecimal globalThan() {
        return BIG_1000;
    }

    public static BigDecimal custom2BigDecimal(BigDecimal amount) {
        return amount == null ? BigDecimal.ZERO : amount.divide(globalThan());
    }

    public static Integer hundred2thousand(BigDecimal amount) {
        return amount == null ? 0 : amount.multiply(BigDecimal.TEN).intValue();
    }

    public static Integer thousand2hundred(Integer amount) {
        return amount == null ? 0 : amount / 10;
    }

    public static void main(String[] args) {
    }
}
